/*	--- 注入配置 --- 

@Value("${..}")  声明
@Value("#{..}")  注入

在【开发应用程序】时，经常需要【读取配置文件】。

【最常用的配置方法】是【以key=value的形式】写在【.properties文件】中。

例如，【MailService】根据【配置的 app.zone=Asia/Shanghai 】来决定【使用哪个时区】。


要【读取配置文件】，我们可以使用上一节讲到的【Resource】来读取【位于classpath下的一个app.properties文件】。

但是，【使用Resource】仍然比较繁琐。

【Spring容器】还提供了一个【更简单的@PropertySource】来【自动读取配置文件】。

	@PropertySource  <-- 自动读取配置文件

我们只需要在【@Configuration配置类】上再添加【一个注解】： */
@Configuration 
@ComponentScan
@PropertySource("app.properties") // 表示读取classpath的app.properties
public class AppConfig {
	@Value("${app.zone:Z}")
	String zoneId;

	@Bean
	ZoneId createZoneId() {
		return ZoneId.of(zoneId);
	}
}


/*
【Spring容器】看到【@PropertySource("app.properties")注解】后，自动读取【这个配置文件】

然后，我们使用【@Value】正常注入： */
@Value("${app.zone:Z}")
String zoneId;


/*
注意【注入的字符串语法】，【它的格式】如下：

	· "${app.zone}" 表示 【读取key为app.zone的value】，如果【key不存在】，【启动】将【报错】；
	· "${app.zone:Z}" 表示 【读取key为app.zone的value】，但如果【key不存在】，就使用【默认值Z】。


这样一来，我们就可以根据【app.zone的配置】来创建【ZoneId】。

还可以把【注入的注解】写到【方法参数】中：*/
@Bean
ZoneId createZoneId(@Value("${app.zone:Z}") String zoneId) {
	return ZoneId.of(zoneId);
}


/*
可见，先【使用@PropertySource】读取【配置文件】，然后通过【@Value】以【${key:defaultValue}的形式】注入，可以极大地简化【读取配置的麻烦】。

-----------------------------------


【另一种注入配置的方式】是先通过【一个简单的JavaBean持有"所有的配置"】

例如，一个SmtpConfig： */
@Component 
public class SmtpConfig {
	@Value("${smtp.host}")
	private String host;

	@Value("${smtp.port:25}")
	private int port;


	public String getHost() {
		return host;
	}

	public int getPort() {
		return port;
	}
}


/*
然后，在需要【读取的地方】，使用【 #{smtpConfig.host} 注入】： */
@Component 
public class MailService {
	@Value("#{smtpConfig.host}")
	private String smtpHost;

	@Value("#{smtpConfig.port}")
	private int smtpPort;
}


/*
注意观察 @Value(#{"..."}) 这种【注入语法】，

它和 ${key} 不同的是，#{} 表示 从【JavaBean】读取属性。

"#{smtpConfig.host}"的意思是，从【名称为smtpConfig的Bean】读取【host属性】，即调用【getHost()方法】。

【一个Class】名为【SmtpConfig的Bean】，【SmtpConfig的Bean】 在【Spring容器】中的【默认名称就是smtpConfig】，除非【用@Qualifier指定了名称】。


使用一个【独立的JavaBean】持有【所有属性】，然后在【其他Bean】中以【#{bean.property}】注入的好处是，【多个Bean】都可以引用【同一个Bean的某个属性】。

例如，如果【SmtpConfig】决定从【数据库】中, 读取【相关配置项】，那么【MailService】注入的【@Value("#{smtpConfig.host}")】仍然可以【不修改正常运行】。


======================================================================


#	练习

注入SMTP配置 */



/*=======================================================================

#	----- 注入配置 の 小结 ----- 

1. Spring容器可以通过@PropertySource自动读取配置，并以@Value("${key}")的形式注入；

2. 可以通过${key:defaultValue}指定默认值；

3. 以#{bean.property}形式注入时，Spring容器自动把指定Bean的指定属性值注入。


*/










































